package com.smedi.ismedi.progress.core.application.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.smedi.ismedi.authority.starter.util.AuthorityUtil;
import com.smedi.ismedi.constructionproject.api.dto.response.ProjectBasicResponse;
import com.smedi.ismedi.inmail.api.dto.request.MessageInfoRequest;
import com.smedi.ismedi.inmail.api.dto.response.TaskRecordResponse;
import com.smedi.ismedi.progress.core.application.command.*;
import com.smedi.ismedi.progress.core.application.query.ConstructionLogQueryService;
import com.smedi.ismedi.progress.core.application.query.ConstructionLogService;
import com.smedi.ismedi.progress.core.application.service.ConstructionLogApplicationService;
import com.smedi.ismedi.progress.core.domain.aggregatemodel.ConstructionLog;
import com.smedi.ismedi.progress.core.domain.aggregatemodel.ConstructionLogDetail;
import com.smedi.ismedi.progress.core.domain.aggregatemodel.Person;
import com.smedi.ismedi.progress.core.domain.dto.PersonQuery;
import com.smedi.ismedi.progress.core.domain.repository.PersonRepository;
import com.smedi.ismedi.progress.core.domain.service.ExportExcelDomainService;
import com.smedi.ismedi.progress.core.domain.service.ProgrressReportDomainService;
import com.smedi.ismedi.progress.core.infrastructure.constant.ConstantField;
import com.smedi.ismedi.progress.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.progress.core.port.adapter.persistence.model.ConstructionLogEntity;
import com.smedi.ismedi.progress.core.port.adapter.persistence.model.ProgressReportEntity;
import com.smedi.ismedi.progress.core.port.adapter.service.TaskRemoteService;
import com.smedi.ismedi.web.starter.exception.ErrorItem;
import com.smedi.ismedi.web.starter.exception.LogicException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.smedi.ismedi.progress.core.infrastructure.constant.ConstantField.*;
import static com.smedi.ismedi.progress.core.infrastructure.constant.ConstantField.SYSTEM_RELEASE;

/**
 * 施工日志应用服务实现类
 *
 * @author pengyan
 * @date 2022/11/23
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ConstructionLogApplicationServiceImpl implements ConstructionLogApplicationService {
    private final ConstructionLogQueryService constructionLogQueryService;
    private final ExportExcelDomainService exportExcelDomainService;
    private final PersonRepository personRepository;
    private final AuthorityUtil authorityUtil;
    private final ConstructionLogService constructionLogService;
    private final TaskRemoteService taskRemoteService;
    private final ProgrressReportDomainService progrressReportDomainService;

    @Value("${message-notify.project-manager.role}")
    private String messageNotifyProjectManagerRole;// 施工项目经理
    @Value("${message-notify.project-constructor.projectjob}")
    private String messageNotifyProjectConstructorProjectjob;// 施工员

    @Override
    public String monthWeekConstructionSaveDraftAndRelease(ConstructionLogSaveAndDraft constructionLogSaveAndDraft) {
         /*保存
         需要给当前登录人生成待办
         如果是发布 需要把状态变成 已发布 待办中的 处理变成已处理  并给施工项目经理发送待办任务*/
        if (null == constructionLogSaveAndDraft.getId()){
            // 查询如果目前 已经存在施工日志就不能添加
            ConstructionLogEntity constructionLogEntity =  constructionLogService.getConstructionLog(constructionLogSaveAndDraft);
            if (null != constructionLogEntity){
                throw LogicException.raise(new ErrorItem(31, "同一个项目只能创建一个施工日志，请修改日期！"));
            }
        }
        List<Person> messageNotifyProjectManager = personRepository.getPersonList(PersonQuery.builder().projectJob(messageNotifyProjectManagerRole).projectId(constructionLogSaveAndDraft.getProjectId()).build());
        ProjectBasicResponse projectData = progrressReportDomainService.getProject(constructionLogSaveAndDraft.getProjectId());
        String projectName = null;
        String projectId = null;
        if (projectData != null){
            if (projectData.getProjectName() != null ){
                projectName = projectData.getProjectName();
                constructionLogSaveAndDraft.setProjectName(projectName);
            }
            if (projectData.getProjectId() != null ){
                projectId = String.valueOf(projectData.getProjectId());
            }
        }
        ConstructionLogSaveAndDraft constructionLog =  constructionLogService.saveReportAndDetial(constructionLogSaveAndDraft);
        ConstructionLogSaveAndDraft constructionLogQuery = constructionLogService.getConstructionLogOne(constructionLog);
        // 保存草稿
        if (DRAFT_METHOD.equals(constructionLogSaveAndDraft.getMethod())){
            constructionLogQuery.setStatus(1l);
            // 查询当前登录人是否有对应的待办信息有不在创建
            List<TaskRecordResponse> taskList = taskRemoteService.queryListTaskRecord(QueryListTaskRecordCommand.builder()
                    .taskType(ConstantField.CONSTRUCTION_TYPE)
                    .dealPersonId(authorityUtil.getPersonId())
                    .projectId(Long.parseLong(projectId))
                    .sourceFromId(constructionLogQuery.getId())
                    .taskStatus("进行中")
                    .taskName(ConstantField.CONSTRUCTION_NAME)
                    .build()
            );
            // 当前登录人生成待办
            if (taskList.size() == 0){
                // 发送待办
                taskRemoteService.createTask(TaskRecordCreateCommand.builder()
                        .sourceFromId(constructionLogQuery.getId())
                        .taskType(ConstantField.CONSTRUCTION_TYPE)
                        .taskName(ConstantField.CONSTRUCTION_NAME)
                        .taskDescribe(constructionLogSaveAndDraft.getLogDate() + ConstantField.CONSTRUCTION_DESCRIBE)
                        .dealPersonId(authorityUtil.getPersonId())// 施工经理id
                        .dealPersonName(authorityUtil.getLoginAccess().getLastName()) // 施工经理名称
                        .taskStatus("进行中")
                        .projectId(Long.parseLong(projectId))
                        .projectName(projectName)
                        .sponsorId(authorityUtil.getPersonId())
                        .sponsorName(authorityUtil.getLoginAccess().getLastName())
                        .startTime(LocalDateTime.now())
                        .build());
            }
        }else if (RELEASE_METHOD.equals(constructionLogSaveAndDraft.getMethod())){
            constructionLogQuery.setReadingStatus(1l);
            constructionLogQuery.setStatus(2l);
            taskRemoteService.editTask(TaskRecordEditCommand.builder()
                    .sourceFromId(constructionLogQuery.getId())
                    .taskType(ConstantField.CONSTRUCTION_TYPE)
                    .taskName(ConstantField.CONSTRUCTION_NAME)
                    .taskStatus("已完成")
                    .oldStatus(new ArrayList<>(Collections.singletonList("进行中")))
                    .finishTime(LocalDateTime.now())
                    .build());
            // 给施工项目经理发送待办
            for (Person person : messageNotifyProjectManager){
                // 发送待办
                taskRemoteService.createTask(TaskRecordCreateCommand.builder()
                        .sourceFromId(constructionLogQuery.getId())
                        .taskType(ConstantField.CONSTRUCTION_TYPE)
                        .taskName(ConstantField.CONSTRUCTION_REVIEW)
                        .taskDescribe(String.valueOf(constructionLogSaveAndDraft.getLogDate()))
                        .dealPersonId(person.getId())// 施工经理id
                        .dealPersonName(person.getName()) // 施工经理名称
                        .taskStatus("进行中")
                        .projectId(constructionLogSaveAndDraft.getProjectId())
                        .projectName(constructionLogSaveAndDraft.getProjectName())
                        .sponsorId(authorityUtil.getPersonId())
                        .sponsorName(authorityUtil.getLoginAccess().getLastName())
                        .startTime(LocalDateTime.now())
                        .build());

            }
        }
        constructionLogService.updateConstructionLog(constructionLogQuery);
        return null;
    }

    @Override
    public ResponseEntity<byte[]> constructionLogExport(ConstructionLogDetailQuery constructionLogDetailQuery) throws IOException {
        if (constructionLogDetailQuery == null){
            throw LogicException.raise(CustomError.NO_DATA_FOUND);
        }
        ConstructionLogDetail constructionLogDetail = getConstructionLogDetail(constructionLogDetailQuery);
        if (constructionLogDetail == null){
            throw LogicException.raise(CustomError.NO_DATA_FOUND);
        }
        return exportExcelDomainService.constructionLogExport(constructionLogDetail);
    }

    @Override
    public ConstructionLogDetail getConstructionLogDetail(ConstructionLogDetailQuery constructionLogDetailQuery) {
        //获取当前项目的 施工项目经理
        List<Person> personList = personRepository.getPersonList(PersonQuery.builder().projectJob(messageNotifyProjectManagerRole).projectId(constructionLogDetailQuery.getProjectId()).build());
        return constructionLogQueryService.getConstructionLogDetail(constructionLogDetailQuery,personList);
    }

    @Override
    public ConstructionLog getConstructionLogAPPList(ConstructionLogListQuery constructionLogListQuery) {
        List<Person> personList;
        if (ObjectUtils.isNotNull(constructionLogListQuery.getProjectId())){
            personList  = personRepository.getPersonList(PersonQuery.builder().projectJob(messageNotifyProjectManagerRole).projectId(constructionLogListQuery.getProjectId()).build());
        }else {
            personList = personRepository.getPersonList(PersonQuery.builder().projectJob(messageNotifyProjectManagerRole).projectId(constructionLogListQuery.getOrganizationOrProjectId()).build());
        }
        return constructionLogQueryService.getConstructionLogAPPList(constructionLogListQuery,personList);
    }

    @Override
    public ResponseEntity<byte[]> downloadBySignKeys(ConstructionLogDownloadQuery constructionLogDownloadQuery) {
        if (constructionLogDownloadQuery == null){
            throw LogicException.raise(CustomError.NO_DATA_FOUND);
        }
        return exportExcelDomainService.downloadBySignKeys(constructionLogDownloadQuery);
    }

    @Override
    public Boolean constructionLogDealt() {
        // 获取所以的项目
        List<ProgressReportEntity> listProgress = progrressReportDomainService.getAllProgressReport();
        listProgress.forEach(v->{
            ProjectBasicResponse projectData = progrressReportDomainService.getProject(v.getProjectId());
            String projectName = null;
            if (projectData != null){
                if (projectData.getProjectName() != null ){
                    projectName = projectData.getProjectName();
                }
            }
            // 施工员
            List<Person> messageNotifyProjectConstructorProject = personRepository.getPersonList(PersonQuery.builder().projectJob(messageNotifyProjectConstructorProjectjob).projectId(v.getProjectId()).build());
            String firstDay = LocalDate.now().toString();
            Integer counet = constructionLogService.findConstructionLog(firstDay,v.getProjectId());
            if(counet == 0){
                if(projectData.getProjectStatus().equals("CONSTRUCTING")){
                    //项目状态为建设中
                    for (Person person : messageNotifyProjectConstructorProject){
                        // 发送消息
                        MessagesSendPostCommand messagesSendPostCommand = new MessagesSendPostCommand();
                        MessageInfoRequest messageInfoRequests = new MessageInfoRequest();
                        List<MessageInfoRequest> listDate = new ArrayList<>();
                        messageInfoRequests.setMessageTitle(ConstantField.CONSTRUCTION_NOT_RELEASE);
                        messageInfoRequests.setMessageType(ConstantField.CONSTRUCTION_TYPE);
                        messageInfoRequests.setProjectId(String.valueOf(v.getProjectId()));
                        messageInfoRequests.setProjectName(projectName);
                        messageInfoRequests.setPushTime(LocalDateTime.now());
                        messageInfoRequests.setSourceFrom(ConstantField.CONSTRUCTION_TYPE);
                        // 发送消息
                        messageInfoRequests.setMessageContent(person.getName() + ConstantField.CONSTRUCTION_CONTEXT + projectName + "。");
                        messagesSendPostCommand.setUserIds(new ArrayList<>(Collections.singletonList(person.getId())));
                        listDate.add(messageInfoRequests);
                        messagesSendPostCommand.setMessageInfoRequests(listDate);
                        taskRemoteService.postSendMessage(messagesSendPostCommand);
                    }
                }

            }
        });
        return true;
    }
}
